/**
 * @brief Calculator Version 3, using inherit feature of OOP.
 * On the basis of the second version of the calculator,
 * the inheritance feature is added: the parent class Operation is extracted, 
 * and the addition and subtraction calculations are inherited from the parent class to 
 * 1. isolate the addition and subtraction operations
 * 2. improve the encapsulation
 * @author fujie
 * @date 2021-06-27 14:32:51
*/

#include <stdio.h>

/**
 * @brief Parent operation class, can be inherited by add class and sub class
*/
class Operation
{
public:
    int adderA, adderB;
    // char symbol; no symbol in parent class
public:
    Operation(/* args */);
    Operation(int a, int b);
    ~Operation();
    virtual int getResult(); // The virtual function of the parent class can be overridden by the child class
};

Operation::Operation(int a, int b)
{
    printf("Constructor of class operation\n");
    adderA = a;
    adderB = b;
}
int Operation::getResult()
{
    int result = 0;
    return result;
}
Operation::Operation(/* args */)
{
    printf("Constructor of class operation\n");
    adderA = 0;
    adderB = 0;
}

Operation::~Operation()
{
    printf("Destructor of class operation\n");
}

/**
 * @brief The addition class is used to perform addition operations
*/
class OperationAdd : public Operation
{
public:
    OperationAdd(/* args */);
    OperationAdd(int a, int b);
    ~OperationAdd();
    int getResult() override;
};
OperationAdd::OperationAdd(int a, int b) : Operation(a, b) // call parent constructor
{
    printf("Constructor of class operationAdd\n");
}
int OperationAdd::getResult()
{
    return adderA + adderB;
}
OperationAdd ::OperationAdd(/* args */)
{
    printf("Constructor of class operationAdd\n");
}

OperationAdd ::~OperationAdd()
{
    printf("Destructor of class operationAdd\n");
}

/**
 * @brief The subtraction class is used to perform subtraction operations
*/
class OperationSub:public Operation
{
public:
    OperationSub(/* args */);
    OperationSub(int a,int b);
    ~OperationSub();

    int getResult() override;
};

int OperationSub::getResult()
{
    return adderA-adderB;
}
OperationSub::OperationSub(int a,int b):Operation(a,b)
{
    printf("Constructor of class operationSub\n");
}
OperationSub::OperationSub(/* args */)
{
    printf("Constructor of class operationSub\n");
}

OperationSub::~OperationSub()
{
    printf("Destructor of class operationSub\n");
}

int main()
{
    int adderA = 0, adderB = 0, result = 0;
    char symbol;
    printf("input adder A: ");
    scanf("%d", &adderA);
    printf("input adder B: ");
    scanf("%d", &adderB);

    printf("input symbol: ");
    getchar();          // get the \n before get char symbol
    symbol = getchar(); // input a char variable

    if (symbol == '+')
    {
        OperationAdd add(adderA, adderB);
        printf("result= %d\n", add.getResult());
    }
    else if(symbol=='-')
    {
        OperationSub sub(adderA,adderB);
        printf("result= %d\n",sub.getResult());
    }

    return 0;
}